package com.lin.mybatis.jsql;

import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.BinaryExpression;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.operators.arithmetic.Addition;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.select.AllColumns;
import net.sf.jsqlparser.statement.select.AllTableColumns;
import net.sf.jsqlparser.statement.select.Select;
import net.sf.jsqlparser.statement.select.SelectItem;
import net.sf.jsqlparser.util.AddAliasesVisitor;
import net.sf.jsqlparser.util.ConnectExpressionsVisitor;
import net.sf.jsqlparser.util.SelectUtils;
import net.sf.jsqlparser.util.TablesNamesFinder;
import org.junit.jupiter.api.Test;

import java.util.List;

/**
 * @author linjiang
 * @date 2024/6/11
 * @fn
 */
public class TestJSqlTool {
    @Test
    public void testCCJSqlParserUtil() throws JSQLParserException {
        String sql = "select * from user where id = 1";
        // CCJSqlParserUtil -> jsql的解析器工具类。就像集合工具类一样（Collections）
        Statement statement = CCJSqlParserUtil.parse(sql);
        if (statement instanceof Select) {
            Select select = (Select) statement;
            System.out.println(select);
        }

        // 解析表达式
        Expression expression = CCJSqlParserUtil.parseExpression("1+2");
        System.out.println(expression);
    }

    @Test
    public void testSelectUtils() throws JSQLParserException {
        //SelectUtils -> 专门用于构建查询语句（Select对象）的工具类
        Table table = new Table("user");

        // SELECT * FROM user
        Select select = SelectUtils.buildSelectFromTable(table);
        System.out.println(select);

        // SELECT user.* FROM user
        SelectItem selectItem = new AllTableColumns(table);
        // SELECT * FROM user
        selectItem = new AllColumns();
        select = SelectUtils.buildSelectFromTableAndSelectItems(table, selectItem);
        System.out.println(select);

        // SELECT id, name, age FROM use
        select = SelectUtils.buildSelectFromTableAndExpressions(table, "id","name","age");
        System.out.println(select);
    }

    @Test
    public void testTablesNamesFinder() throws JSQLParserException {
        String sql = "select * from A left join B on A.id = B.id where A.id = 1";
        Statement statement = CCJSqlParserUtil.parse(sql);

        // TablesNamesFinder -> 专门用于获取SQL中所有表名称的工具类
        TablesNamesFinder finder = new TablesNamesFinder();
        List<String> tableList = finder.getTableList(statement);
        for (String tableName : tableList) {
            System.out.println(tableName);
        }
    }

    @Test
    public void testConnectExpressionsVisitor() throws JSQLParserException {
        String sql = "select a,b,c from user";
        Statement statement = CCJSqlParserUtil.parse(sql);
        // ConnectExpressionsVisitor -> 将表中的所查询额字段使用特定的连接符进行连接。
        ConnectExpressionsVisitor visitor = new ConnectExpressionsVisitor("abc") {
            @Override
            protected BinaryExpression createBinaryExpression() {
                return new Addition();
            }
        };

        if (statement instanceof Select) {
            Select select = (Select) statement;
            select.getSelectBody().accept(visitor);
            System.out.println(select);
        }
    }

    @Test
    public void testAddAliasesVisitor() throws JSQLParserException {
        String sql = "select a,b,c from user";
        Statement statement = CCJSqlParserUtil.parse(sql);

        // AddAliasesVisitor -> 将表中的所查询的字段分别添加别名，默认是从A1（A1~An）开始。
        AddAliasesVisitor visitor = new AddAliasesVisitor();
        visitor.setPrefix("t");

        if (statement instanceof Select) {
            Select select = (Select) statement;
            select.getSelectBody().accept(visitor);
            System.out.println(select);
        }
    }
}
